<?php
class cUrl{

	private $options = array();
	private $reqHeaders = array();
	private $resHeaders = array();
	private $info = array();
	private $url = null;
	private $lastResult = null;
	public $success = null;
	public $error = null;
	public $_parse = null;
	
	/**
	 * Constrtuctor method
	 *
	 * @param array $options	curl_setopt options
	 */
	public function __construct($options = null)
	{
		if (!extension_loaded('curl') && !@dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
			$this->error = 'Unable to load CURL extension';
			$this->success = false;
			trigger_error($this->error,E_USER_ERROR);
			return false;
		}
		$this->setOptions($options);
	}
	/**
	 * set options
	 *
	 * @param array $options	curl_setopt options
	 */
	public function setOptions($options = null)
	{
		$this->reqHeaders = array();
		$this->options['CURLOPT_HEADER']			= 0;							// no headers in result
		$this->options['CURLOPT_NOBODY'] 			= 0;							// include body in response
		$this->options['CURLOPT_USERAGENT']			= $_SERVER['HTTP_USER_AGENT'];	// pass user agent
		$this->options['CURLOPT_FOLLOWLOCATION']	= 1;							// allow redirection
		$this->options['CURLOPT_MAXREDIRS']			= 10;							// max redirects
		$this->options['CURLOPT_TIMEOUT']			= 60;							// max time in seconds
		$this->options['CURLOPT_ENCODING']			= "";							// allow curl to manage decoding
		$this->options['CURLOPT_RETURNTRANSFER']	= 1;							// return results as string
		$this->options['CURLOPT_BINARYTRANSFER']	= 0;							// no binary transfer
		$this->options['CURLOPT_SSL_VERIFYPEER']	= 0;							// don't verify ssl certs
		$this->options['CURLOPT_COOKIEJAR']			= $_SERVER['DOCUMENT_ROOT'].'/curl_cookies.txt';
		$this->options['CURLOPT_COOKIEFILE']		= $_SERVER['DOCUMENT_ROOT'].'/curl_cookies.txt';
		$this->options['CURLOPT_REFERER']			= @(($_SERVER['HTTPS']=='on') ? 'https:' : 'http:').'//'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
		if (is_array($options)) {
			foreach($options as $opt => $val) $this->setOption($opt,$val);
		}
	}
	/**
	 * set a single option
	 *
	 * @param string $option	curl_setopt option name
	 * @param mixed $value		curl_setopt value
	 */
	public function setOption($option, $value)
	{
		if (substr($option,-11) == 'ASYNCRONOUS') {
			$option = "CURLOPT_TIMEOUT";
			$value = ($value) ? 1 : $this->options['CURLOPT_TIMEOUT'];
		}
		$this->options[str_replace(array('HTTP_','STREAMS_'),'CURLOPT_',$option)] = $value;
		if (substr($option,-11) == 'ASYNCRONOUS') $this->options['CURLOPT_NOBODY'] = 1;

	}
	/**
	 * http GET request
	 *
	 * @access public
	 * @param string $url 		the request url
	 * @param array $options 	additional options
	 */
	public function get($url, $options = null) 
	{
		$this->_resetOpt();
		if (is_array($options)) 
			foreach($options as $opt => $val) $this->setOption($opt,$val);
		$this->options['CURLOPT_HTTPGET'] = 1;
		return $this->httpRequest($url);
	}
	/**
	 * http OPTIONS request
	 *
	 * @access public
	 * @param string $url 		the request url or '*'
	 * @param array $options 	additional options
	 */
	public function options($url, $options = null) 
	{
		$this->_resetOpt();
		if (is_array($options)) 
			foreach($options as $opt => $val) $this->setOption($opt,$val);
		$this->options['CURLOPT_HEADER'] = 1;
		$this->options['CURLOPT_NOBODY'] = 1;
		$this->options['CURLOPT_CUSTOMREQUEST'] = "OPTIONS";
		return $this->httpRequest($url);
	}
	/**
	 * http request
	 *
	 * @access public
	 * @param string $url 		the request url
	 */
	public function httpRequest($url) 
	{
		//$this->header('X-EAC-Request: '.$this->Signature);
		$url = str_replace('&amp;','&',$url);
		$ch = curl_init($url);

		if (!empty($this->options['CURLOPT_USERPWD']) && !isset($this->options['CURLOPT_HTTPAUTH'])) {
			$this->options['CURLOPT_HTTPAUTH'] = CURLAUTH_ANY;
		}

		if (count($this->reqHeaders) > 0) {
			curl_setopt($ch, CURLOPT_HTTPHEADER, $this->reqHeaders);
		}
		foreach($this->options as $opt => $val) {
			if (is_string($opt)) $opt = constant(strtoupper($opt));
			curl_setopt($ch, $opt, $val);
		}
		//curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this,'_parseHeaders'));

		$this->lastResult = curl_exec($ch);
		$this->info = curl_getinfo($ch);

		if (substr($this->info['http_code'],0,1) == 2) {
			if ($this->lastResult && isset($this->resHeaders['Content-Encoding']) &&
				stripos($this->resHeaders['Content-Encoding'],"gzip") !== false) {
				if (!isset($this->options['CURLOPT_ENCODING'])) $this->lastResult = $this->_gzdecode($this->lastResult);
				$this->info['decoded_content_length'] = strlen($this->lastResult);
			}
			
			$this->success = true;
		} else {
			$this->error = curl_error($ch);
			$this->success = false;
			$this->lastResult = $this->error;
		}
		curl_close($ch);
		return $this->lastResult;
	}
	
	/**
	 * Get http statuscode (Tarjei)
	 *
	 * @return int
	 */
	public function getHttpStatus()
	{
	  return $this->info['http_code'];
	}
	 
	 
	/**
	 * get last result
	 *
	 * @access public
	 */
	public function getLastResult() 
	{
		return $this->lastResult;
	}

	/**
	 * get htttp request url
	 *
	 * @return public
	 */
	public function getUrl() 
	{
		return $this->url;
	}

	public function setUrl($url){
		$this->url = $url;
	}
	

	/**
	 * get response info
	 *
	 * @param string|null $field to get a single info field
	 * @access public
	 */
	public function getInfo($field=null) 
	{
		return $this->info;
	}
	/**
	 * get options array
	 *
	 * @param string $option to get a single option
	 * @access public
	 */
	public function getOptions($option=null) 
	{
		if ($option) {
			$option = str_replace(array('HTTP_','STREAMS_'),'CURLOPT_',$option);
			return (isset($this->options[$option])) ? $this->options[$option] : null;
		}
		return $this->options;
	}
	/**
	 * unset function parameters
	 * 
	 */
	private function _resetOpt() 
	{
		unset($this->options['CURLOPT_HTTPGET']);
		unset($this->options['CURLOPT_POST']);
		unset($this->options['CURLOPT_POSTFIELDS']);
		unset($this->options['CURLOPT_PUT']);
		unset($this->options['CURLOPT_INFILE']);
		unset($this->options['CURLOPT_INFILESIZE']);
		unset($this->options['CURLOPT_CUSTOMREQUEST']);
		$this->options['CURLOPT_HEADER'] = 0;
		$this->options['CURLOPT_NOBODY'] = 0;
		$this->resHeaders = array();
	}
	public function getData($url){
		$this->setUrl($url);
		//$this->getthumbimg($this->url);exit;
		$this->data['url'] = NParseUrl::getUrlinfo($url);
		$this->_parse = new NParseUrl($url);
		if(!$url){
			$this->data['success']		= 0;
			$this->data['error']		="地址不能为空";
			return $this->data;
		}
		$this->httpRequest($url);
		if($this->success){
			$charset = trim(strtoupper($this->getCharset()));
			if(!$charset || $charset == 'UTF'){
				$this->data['title']		=$this->getTitle();
				$this->data['description']	=$this->getDescription();
				$this->data['keyword']		=$this->getKeywords();
			}else{
				$this->data['title']		=iconv($charset,"UTF-8//IGNORE",$this->getTitle());
				$this->data['description']	=iconv($charset,"UTF-8//IGNORE",$this->getDescription());
				$this->data['keyword']		=iconv($charset,"UTF-8//IGNORE",$this->getKeywords());
			}
			//$this->data['img']		=$this->getImages();
			$this->data['success']		= 1;
		}else{
			$this->data['success']		= 0;
			$this->data['error']		=$this->error;
			$this->data['info']			=$this->getInfo();
		}
		return $this->data;
	}
	public function getTitle(){
		if(!$this->success)return '';
		$ereg_title = "/<\s*title\s*>((\n*|.)*)<\s*\/title\s*>/i";
		//$ereg_title = "/(?<=<title\s*[^>]*>)(.*)(?=<\/title>)/";
		if(preg_match($ereg_title,$this->lastResult,$match)){
			return $match[1];
		}
	}
	public function getDescription(){
		if(!$this->success)return '';
		$str = "\"|'";
		$ereg_desc1 = "/<\s*meta\s+name\s*=\s*(". $str .")\s*description\s*\\1\s+content\s*=\s*\\1(^>]+)\\1\s*\/*\s*>/i";
		$ereg_desc2 = "/<\s*meta\s+content\s*=\s*(". $str .")\s*(^>]+)\s*\\1\s+name\s*=\s*\\1\s*description\s*\\1\s*\/*\s*>/i";
		if(preg_match($ereg_desc1,$this->lastResult,$match)){
			return $match[2];
		}elseif(preg_match($ereg_desc2,$this->lastResult,$match)){
			return $match[2];
		}
	}
	
	public function getKeywords(){
		if(!$this->success)return '';
		$str = "\"|'";
		$ereg_key1 = "/<\s*meta\s+name\s*=\s*(". $str .")\s*keywords\s*\\1\s+content\s*=\s*\\1(^>]+)\\1\s*\/*\s*>/i";
		$ereg_key2 = "/<\s*meta\s+content\s*=\s*(". $str .")(^>]+)\\1\s+name\s*=\s*\\1\s*keywords\s*\\1\s*\/*\s*>/i";
		if(preg_match($ereg_key1,$this->lastResult,$match)){
			return $match[2];
		}elseif(preg_match($ereg_key2,$this->lastResult,$match)){
			return $match[2];
		}
	}
	public function getCharset(){
		if(!$this->success)return '';
		$ereg = "/charset\s*=\s*(\w*)\s*/i";
		if(preg_match($ereg,$this->lastResult,$match)){
			return $match[1];
		}
	}
	public function getImages(){
		if(!$this->success)return '';
		$ereg_img = "/<img\s?([^src]*)\s*src\s*=\s*[\"|\']?\s*([^>\"\'\s]*)/i";
		$imgs = array();
		$imgs_big[] = $this->getThumbimg();
		if(preg_match_all($ereg_img,$this->lastResult,$match)){
			if(!empty($match[2])){
				$imgs = $this->parseImgSrc($match[2]);
			}
		}
		return ($imgs_big+$imgs);
	}
	private function parseImgSrc($img){
		if(is_array($img)){
			foreach($img as $k => $src){
				$currentSrc[] = NParseUrl::getUrlinfo($src,$this->getUrl());
			}
			return $currentSrc;
		}
	}
	public function getThumbimg(){
		return Thumb::grabThumb($this->url);
	}
}
